When creating frameworks programmers want extensibility in several dimensions; they want to add new types and they want to add new functionality. Traditional imperative languages and modem functional languages make it easy to add new functions (since functions are defined independently from types), but make it hard to add new types (since this would require dealing with this new type in all existing functions).
Object-oriented languages on the other hand, make it easy to add new types, but make hard to add new functions (since this would require adding new methods to all existing types). For constructed types (such as IEnumerable<string>) it is even impossible to add new methods, since there is no class declaration for that particular type to add these new methods. A typical example that requires both forms of extensibility is in compiler construction.
This extensibility dilemma is what is called “the expression problem”. This fundamental dilemma of programming is the desire that an application can be structured in such a way that both the data model and the set of virtual operations over it be extended without the need to modify existing code, without the need for code repetition and without runtime type errors.